﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModeloGaleriaNET;
using MySql.Data.MySqlClient;
using System.Data.Objects;
using System.Security.Cryptography;

namespace CADs
{
    public class UsuarioCAD : BaseCAD
    {
       private int queryCount;
       private List<UsuarioFilter> filtros;

       public UsuarioCAD() : base() 
       {
           filtros = new List<UsuarioFilter>();
       }

       public List<Usuario> GetAllUsuario()
       {
           return contexto.Usuarios.Where(u => u.Activo).OrderBy(u => u.Id).ToList();
       }

       public dynamic GetUsuariosIdNombre()
       {
           return contexto.Usuarios.ToList().Select(u => new { u.Id, u.PseudonimoLocal })
               .OrderBy(u => u.PseudonimoLocal);
       }

       public Usuario GetUsuarioByLoginPassword(string login, string password)
       {
           List<Usuario> usuarios;
           
           usuarios = contexto.Usuarios.Where(u => u.Activo && u.PseudonimoLocal.ToLower().Equals(login.ToLower()) 
               && u.Password.Equals(password)).ToList();
           if (usuarios == null || usuarios.Count == 0)
               return null;

           return usuarios.First();
       }

       public List<Usuario> GetUsuariosPaginated(int pagenum = 0)
       {
           int pagesize = int.Parse(Properties.Resources.PageSize);
           ObjectQuery<Usuario> query;
           
           query = contexto.Usuarios;
           query.MergeOption = MergeOption.OverwriteChanges;

           foreach (var filtro in filtros)
                query = query.Where(filtro.Condition, filtro.Parameters.ToArray());
           
           queryCount = query.Count();

           return query.Skip("it.Id", "@Skip", new ObjectParameter("Skip", pagenum * pagesize))
                       .Top("@Limit", new ObjectParameter("Limit", pagesize))
                       .ToList();
       }

       public void SetQueryFilters(List<UsuarioFilter> filters)
       {
           if (filters == null || filters.Count == 0)
           {
               filtros.Clear();
               this.filtros = new List<UsuarioFilter>();
               filtros.Add(new UsuarioFilter(@"it.activo = true"));
           }
           else
               this.filtros = filters;
       }
        
       /// <summary>
       /// Devuelve el número de usuarios que cumplen la query
       /// </summary>
       /// <returns>Número de usuarios que cumplen la query</returns>
       public int GetUsuariosCount()
       {
           return queryCount;
       }

       public bool BorrarUsuario(Usuario u)
       {
           try
           {
               u.Activo = false;
               SaveChanges();
               return true;
           }
           catch (Exception)
           {
               return false;
           }
       }

       public Usuario GetUsuarioByDNI(string dni)
       {
           IQueryable<Usuario> usuarios = contexto.Usuarios.Where(u => u.Activo && u.Dni.Equals(dni));

           if (usuarios == null || usuarios.Count() == 0)
               return null;
           return usuarios.First();
       }

       public Usuario GetUsuarioByNombreUsuario(string nombreUsuario)
       {
           IQueryable<Usuario> usuarios = contexto.Usuarios.Where(u => u.Activo && u.PseudonimoLocal.ToLower().Equals(nombreUsuario.ToLower()));

           if (usuarios == null || usuarios.Count() == 0)
               return null;
           return usuarios.First();
       }

       public bool GuardarNuevoUsuario(Usuario u)
       {
           try
           {
               contexto.AddToUsuarios(u);
               SaveChanges();
               return true;
           }
           catch (Exception)
           {
               return false;
           }
       }

       public bool GuardarCambios(int id, int rolAntiguo, int rolActual)
       {
           try
           {
               if (rolAntiguo != rolActual)
               {
                   // De usuario a administrador
                   if (rolActual == 1)
                       CambiarRolDeUsuarioAAdministrador(id);
                   // De administrador a usuario
                   else if (rolActual == 0)
                       CambiarRolDeAdministradorAUsuario(id);
               }
               
               SaveChanges();
               return true;
           }
           catch (Exception)
           {
               return false;
           }
       }

       private void CambiarRolDeUsuarioAAdministrador(int id)
       {
           contexto.Detach(contexto.Usuarios.Where(u => u.Id == id).First());
           contexto.ExecuteStoreCommand(@"insert into administradores (id) values (@idInput)", new MySqlParameter("idInput", id));  
       }

       private void CambiarRolDeAdministradorAUsuario(int id)
       {
           contexto.Detach(contexto.Usuarios.Where(u => u.Id == id).First());
           contexto.ExecuteStoreCommand(@"delete from administradores where id = @idInput", new MySqlParameter("idInput", id));
       }
    }
}
